package com.hmall.service;

import com.google.common.collect.HashMultimap;
import com.google.common.collect.Multimap;
import com.google.gson.Gson;
import com.hdmall.business.common.common.ServerResponse;
import com.hdmall.business.common.util.RabbitUtil;
import com.hmall.controller.JpushController;
import com.hmall.mapper.*;
import com.hmall.model.*;
import com.hmall.vo.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.Transaction;
import redis.clients.jedis.Tuple;

import java.io.IOException;
import java.math.BigDecimal;
import java.util.*;

/**
 * @ClassName AuctionService
 * @Description
 * @Author zhoutao
 * @Date 2018/12/26 11:12
 * @Version 2.0
 **/
@Slf4j
@Service
public class AuctionService {

    private final MallAuctionMapper mallAuctionMapper;

    private final MallAuctionItemMapper mallAuctionItemMapper;

    private final MallAuctionHistoryMapper mallAuctionHistoryMapper;

    private final MallAuctionApplyMapper mallAuctionApplyMapper;

    private final MallProductMapper mallProductMapper;

    private final JedisPool jedisPool;

    private final SysUserMapper userMapper;

    private final String AuctionPool = "Auction:Pool";

    private final JpushController jpushController;

    private final SysUserDeptMapper sysUserDeptMapper;

    private final static String AUCTION_PUBLIC_EXCHG = "hdmall_auction_public_exchg";

    private final static String AUCTION_DEFAULT_IMG = "http://hd-yun.oss-cn-hangzhou.aliyuncs.com/imgupload/1547015340411.jpg?Expires=1862375335&OSSAccessKeyId=LTAI0AE4IXlOaSaX&Signature=6JVBLn4ThnmQVjv0VyUuM4o1guQ%3D";

    private final static String QUEUE_PRE = "Auction-";
    @Autowired
    public AuctionService(MallAuctionHistoryMapper mallAuctionHistoryMapper, MallAuctionItemMapper mallAuctionItemMapper, MallAuctionMapper mallAuctionMapper, JedisPool jedisPool, MallAuctionApplyMapper mallAuctionApplyMapper, JpushController jpushController, SysUserMapper userMapper, SysUserDeptMapper sysUserDeptMapper, MallProductMapper mallProductMapper) {
        this.mallAuctionHistoryMapper = mallAuctionHistoryMapper;
        this.mallAuctionItemMapper = mallAuctionItemMapper;
        this.mallAuctionMapper = mallAuctionMapper;
        this.jedisPool = jedisPool;
        this.mallAuctionApplyMapper = mallAuctionApplyMapper;
        this.jpushController = jpushController;
        this.userMapper = userMapper;
        this.sysUserDeptMapper = sysUserDeptMapper;
        this.mallProductMapper = mallProductMapper;
    }

    /**
     * @return com.hmall.common.ServerResponse<com.hmall.vo.AuctionVo>
     * @Date 2018/12/26 11:14
     * @Param [type]
     * @Description  列出竞拍列表
     */
    public ServerResponse listAuction(Integer userId, Integer type, Integer pageNum, Integer pageSize) {
        //0表示预热
        //1表示竞拍中
        //2表示竞拍结束
        if (type == 1 || type == 2 || type == 0) {
            try (Jedis jedis = jedisPool.getResource()) {
                int actionCount = mallAuctionMapper.selectCountByStatus(type);
                int start = (pageNum - 1) * pageSize;
                int end = Math.min(start + pageSize, actionCount);

                List<MallAuction> mallAuctionList = mallAuctionMapper.selectByStatus(type, start, end);
                List<AuctionVo> auctionVoList = new ArrayList<>();
                for (MallAuction mallAuction : mallAuctionList) {
                    //会在常量池重复创建字符串 但是竞拍数目不是很多，让GC自动回收
                    String key = AuctionPool + mallAuction.getPackageNo();
                    String selfPrice = "";
                    if (jedis.exists(key + "-" + userId)) {
                        //一个String类型保存userId的价格
                        //另一个set-sort保存价格排序
                        selfPrice = jedis.get(key + "-" + userId);
                    }
                    //要划去nc等状态变成2
                    int status = mallAuction.getStatus();
                    if(status == 4){
                        status = 2;
                    }

                    Calendar calendar = Calendar.getInstance();
                    Date nowTime = calendar.getTime();
                    long restTime;
                    //2019/1/3
                    //预热的竞拍是距离开始多久
                    //竞拍中是距离结束多久
                    if(type == 0){
                        restTime = mallAuction.getStartTime().getTime() - nowTime.getTime();
                    }else if(type == 1){
                        restTime = mallAuction.getEndTime().getTime() - nowTime.getTime();
                    }else{
                        restTime = 0;
                    }


                    AuctionVo.Builder builder = new AuctionVo.Builder();
                    builder.packageNo(mallAuction.getPackageNo().toString())
                            .packageName(mallAuction.getPackageName())
                            .startTime(mallAuction.getCreateTime())
                            .endTime(mallAuction.getEndTime())
                            .startPrice(mallAuction.getStartPrice())
                            .lowestPrice(mallAuction.getLowestPrice())
                            .status(status);
                    if(restTime >= 0){
                        builder.restTime(restTime);
                    }
                    //竞拍资格
                    //0表示申请中 1表示申请成功 2表示申请失败但是能够继续提交
                    MallAuctionApply mallAuctionApply = mallAuctionApplyMapper.selectByPackageNo(userId, mallAuction.getPackageNo());
                    int applyStatus;
//                    if(mallAuctionApply != null) {
//                        if (mallAuctionApply.getStatus() == 2) {
//                            applyStatus = 1;
//                        } else if(mallAuction.getStatus() == 1){
//                            applyStatus = 2;
//                        }else{
//                            applyStatus = mallAuctionApply.getStatus();
//                        }
//                    }else{
//                        applyStatus = 2;
//                    }
                    if(mallAuctionApply == null){
                        applyStatus = -1;
                    }else{
                        applyStatus = mallAuctionApply.getStatus();
                    }
                    builder.applyStatus(applyStatus);

                    if (type == 1) {
                        //最高价是redis的有序集合里面的
                        builder.highestPrice(getHighestPrice(jedis, key));
                        if (!"".equals(selfPrice)) {
                            builder.selfPrice(new BigDecimal(selfPrice));
                        }else{
                            builder.selfPrice(new BigDecimal(0.0));
                        }
                        builder.auctionCount(mallAuction.getAuctionCount());
                    }

                    if (type == 2) {
                        builder.finishPrice(mallAuction.getHighestPrice());
                    }

                    AuctionVo auctionVo = new AuctionVo(builder);
                    auctionVoList.add(auctionVo);

                }
                PageVo pageVo = new PageVo(pageNum, pageSize, actionCount, auctionVoList);
                return ServerResponse.createBySuccess(pageVo);
            }
        } else {
            return ServerResponse.createByErrorMessage("请输入正确的列表状态, 0预热，1竞拍中，2竞拍结束");
        }
    }

    /**
     * @return java.math.BigDecimal
     * @Date 2018/12/26 13:57
     * @Param [jedis, key]
     * @Description  为了得到最高价格
     */
    private BigDecimal getHighestPrice(Jedis jedis, String key) {

        BigDecimal highestPrice = new BigDecimal(0.0);
        if (jedis.exists(key)) {
            Set<String> userIdList = jedis.zrevrange(key, 0, 1);
            String highestUserId = userIdList.iterator().next();
            highestPrice = new BigDecimal(jedis.zscore(key, highestUserId));
        }
        return highestPrice.setScale(4, BigDecimal.ROUND_HALF_DOWN);
    }

    /**
     * @return java.lang.Integer
     * @Date 2018/12/26 14:55
     * @Param [jedis, key]
     * @Description  得到竞拍最高价的人
     */
    private Integer getHighestUserId(Jedis jedis, String key) {
        if (jedis.exists(key)) {
            Set<String> userIdList = jedis.zrevrange(key, 0, 1);
            String highestUserId = userIdList.iterator().next();
            return Integer.valueOf(highestUserId);
        } else {
            return -1;
        }
    }

    /**
     * @return void
     * @Date 2018/12/26 15:27
     * @Param [jedis, packageNo]
     * @Description  更新竞拍历史
     */
    private void updateAuctionHistory(Jedis jedis, Long packageNo) {

        //2019/1/14
        // problem
        //定时任务重复执行三次

        //把redis里面的数据更新到mysql数据库中
        String key = AuctionPool + packageNo;
        if (jedis.exists(key)) {
            int highestUserId = Integer.valueOf(jedis.zrevrange(key, 0, -1).iterator().next());
            Set<Tuple> userInformationList = jedis.zrangeWithScores(key, 0, -1);
            BigDecimal price;
            MallAuctionHistory mallAuctionHistory = new MallAuctionHistory();
            for (Tuple tuple : userInformationList) {
                Integer userId = Integer.valueOf(tuple.getElement());
                price = new BigDecimal(tuple.getScore());
                mallAuctionHistory.setPackageNo(packageNo);
                mallAuctionHistory.setPrice(price);
                mallAuctionHistory.setUserId(userId);
                if (userId.equals(highestUserId)) {
                    mallAuctionHistory.setFlag(1);
                } else {
                    mallAuctionHistory.setFlag(0);
                }
                jedis.del(key + "-" + userId);

                //插入之间进行查询
                checkPackage(userId, packageNo, mallAuctionHistory);

            }
            //然后删除竞拍用户行为数据
            //删除池子
            jedis.del(key);
            //删除个人的信息
        }
    }

    @Transactional
   void checkPackage(Integer userId, Long packageNo, MallAuctionHistory mallAuctionHistory){

        int count = mallAuctionHistoryMapper.selectByUserIdAndPackageNo(userId, packageNo);
        if(count == 0) {
            mallAuctionHistoryMapper.insert(mallAuctionHistory);
        }
    }

    /**
     * @return com.hmall.common.ServerResponse
     * @Date 2018/12/26 14:05
     * @Param [userId, price, packageNo]
     * @Description  参与竞拍
     */
    public ServerResponse postAuction(Integer userId, BigDecimal price, Long packageNo, SysUser user) {

        SysUserDept sysUserDept = sysUserDeptMapper.selectbyUserId(userId);
        if(sysUserDept == null){
            return ServerResponse.createByErrorMessage("您还未绑定公司，无法进行正常竞拍流程");
        }
        //找到当前的竞拍项目
        MallAuction mallAuction = mallAuctionMapper.selectByPackageNo(packageNo);

        //检验是否有竞拍资格
        MallAuctionApply mallAuctionApply = mallAuctionApplyMapper.selectByPackageNo(userId, packageNo);
        Boolean check = (mallAuctionApply == null || ((mallAuctionApply != null) && !(mallAuctionApply.getStatus() == 2)));
        if(check){
           return ServerResponse.createByErrorMessage("您没有竞拍资格");
        }

        //如果当前时间已经超时，把竞拍关闭
        //jdk1.7之后会自动关闭，反编译后发现只是帮忙写了close而已继承closealbe和使用clean
        try (Jedis jedis = jedisPool.getResource()) {
            Calendar calendar = Calendar.getInstance();
            Date nowDate = calendar.getTime();
            if (mallAuction.getEndTime().getTime() < nowDate.getTime()) {
                //两种情况
                //1.没有人参与竞拍 进入流拍状态
                //2.有人参与竞拍   进入竞拍成功状态

                String key = AuctionPool + packageNo;

                BigDecimal highestPrice = getHighestPrice(jedis, key);
                int status;
                if (highestPrice.doubleValue() == 0) {
                    status = 3;
                } else {
                    status = 2;
                }
                //更新当前竞拍的状态
                mallAuctionMapper.updateStatus(packageNo, status);
            }


            //校验现在是否满足比最高价要高
            String key = AuctionPool + packageNo;
            BigDecimal highestPrice = getHighestPrice(jedis, key);
            if (price.doubleValue() < highestPrice.doubleValue()) {
                return ServerResponse.createByErrorMessage("您的价格低于最高加价，请您重新出价");
            }
            if (price.doubleValue() - highestPrice.doubleValue() < mallAuction.getLowestPrice().doubleValue()) {
                return ServerResponse.createByErrorMessage("您的价格低于最高价格加上最低加价，请您重新出价");
            }

            //可以成功，更新redis中个人价格以及sort-set集群价格
            jedis.watch(key + "-" + userId, key);
            Transaction transaction = jedis.multi();
            transaction.set(key + "-" + userId, price.toString());
            transaction.zadd(key, price.doubleValue(), userId.toString());
            transaction.exec();
            transaction.close();
            jedis.unwatch();

            //对竞拍实体做+1操作
            mallAuctionMapper.addAuctionCount(packageNo);
            //添加操作在查操作之前
            int mallAuctionCount = mallAuctionMapper.selectByPackageNo(packageNo).getAuctionCount();
            //做一个推送动作 json包括auctionCount和highestPrice
            Map map = new HashMap<>(5);
            map.put("auctionCount", mallAuctionCount);
            map.put("highestPrice", price.toString());
            map.put("packageNo", packageNo.toString());
            Gson gson = new Gson();
            String message = gson.toJson(map);
            try {
                RabbitUtil.rabbitPushForQueue(AUCTION_PUBLIC_EXCHG, QUEUE_PRE + packageNo.toString(), message);
            }catch (Exception e){
                log.info("推送失败");
            }
        } catch (IOException e) {
            return ServerResponse.createByErrorMessage("最高价已更新，请重新出价");
        }
        return ServerResponse.createBySuccess("您已竞价成功，请耐心等待");
    }

    /**
     * @return com.hmall.common.ServerResponse
     * @Date 2018/12/26 14:19
     * @Param [userId, packageNo]
     * @Description  列出竞拍的具体产品
     */
    public ServerResponse listAuctionProduct(Long packageNo) {

        List<AuctionProductVo> auctionProductVoList = mallAuctionItemMapper.selectVoByPackageNo(packageNo);
        MallAuction mallAuction = mallAuctionMapper.selectByPackageNo(packageNo);
        //把name重新封装一下
        for (AuctionProductVo auctionProductVo : auctionProductVoList) {

            String grade = auctionProductVo.getGrade();
            if(grade.contains("定重")){
                if(grade.contains("不")){
                    grade = "AA不定重";
                }else{
                    grade = "AA定重";
                }
            }
            auctionProductVo.setGrade(grade);


            String name = auctionProductVo.getName();
            String[] nameStr = name.split(",", -1);
            String type = nameStr[0];
            String model = nameStr[2];
            String fineAndPore = nameStr[3] + "dtex" + nameStr[4] + "f";
            String twisting = nameStr[9];
            auctionProductVo.setType(type);
            auctionProductVo.setModel(model);
            auctionProductVo.setFineAndPore(fineAndPore);
            auctionProductVo.setTwisting(twisting);
            auctionProductVo.setPackageName(mallAuction.getPackageName());
            //2019/1/7 PC端要图片
            String img = mallProductMapper.selectByProductId(auctionProductVo.getProductId()).getMainImage().split(",", -1)[0];
            auctionProductVo.setImg(img);
        }
        //等级和productId一样的要合并
        List<AuctionProductVo> newAuctionProductVoList = new ArrayList<>();
        Multimap map = HashMultimap.create();
        for(AuctionProductVo auctionProductVo : auctionProductVoList){
                map.put(auctionProductVo.getGrade() + auctionProductVo.getProductId(), auctionProductVo);
        }
        for(Object str : map.keySet()){
            Iterator iter =  map.get(str).iterator();
            int count = 0;
            AuctionProductVo auctionProductVo = new AuctionProductVo();
            while(iter.hasNext()){
                if(count == 0) {
                     auctionProductVo = (AuctionProductVo) iter.next();
                    count = 1;
                    continue;
                }
                auctionProductVo.setWeight(auctionProductVo.getWeight().add(((AuctionProductVo) iter.next()).getWeight()));
            }
            newAuctionProductVoList.add(auctionProductVo);
        }

        return ServerResponse.createBySuccess(newAuctionProductVoList);
    }

    /**
     * @return com.hmall.common.ServerResponse
     * @Date 2018/12/26 14:40
     * @Param []
     * @Description  修改竞拍状态
     */
    public ServerResponse updateAuctionStatus(Integer type) {

        //先拉出具体的满足条件的竞拍条目，然后进行轮询查看是否有超时的，进行剔除
        List<MallAuction> mallAuctionList = mallAuctionMapper.selectByStatus(type - 1, 0, 999);
        //sql查询需要时间
        Calendar calendar = Calendar.getInstance();
        Date nowTime = calendar.getTime();
        //防止频繁连接
        try (Jedis jedis = jedisPool.getResource()) {
            for (MallAuction mallAuction : mallAuctionList) {
                if (type == 1) {
                    //变为竞拍中
                    Boolean check = (nowTime.getTime() >= mallAuction.getStartTime().getTime()) ;
                    //2019/1/15如果定时任务挂了
                    //&& (nowTime.getTime() < mallAuction.getEndTime().getTime());
                    if (check) {
                        mallAuctionMapper.updateStatus(mallAuction.getPackageNo(), 1);
                        int rejectStatus = 1;
                        mallAuctionApplyMapper.updateOpinionByPackageNo("审核信息异常，请联系客服",mallAuction.getPackageNo());
                        mallAuctionApplyMapper.updateStatusByPackageNo(rejectStatus, mallAuction.getPackageNo());

                    }
                    //相当于系统人在redis set中插入了一个值
                    jedis.zadd(AuctionPool + mallAuction.getPackageNo(), mallAuction.getStartPrice().doubleValue(), "0");
                    //还需要维护申请表 所有申请中的都变成被拒绝

                } else if (type == 2) {
                    BigDecimal highestPrice;

                    highestPrice = getHighestPrice(jedis, AuctionPool + mallAuction.getPackageNo());

                    //如果是结束先需要看redis上的最高价格取下来然后更新
                    if (nowTime.getTime() > mallAuction.getEndTime().getTime()) {
                        if (highestPrice.doubleValue() == 0) {
                            mallAuctionMapper.updateStatus(mallAuction.getPackageNo(), 3);
                        } else {
                            //竞价成功
                            //1.更新价格
                            //2.更新拥有者
                            //3.更新状态
                            Integer highestUserId = getHighestUserId(jedis, AuctionPool + mallAuction.getPackageNo());
                            mallAuctionMapper.updateAuctionSuccess(mallAuction.getPackageNo(), highestPrice);

                            //插入历史表 更新数据
                            updateAuctionHistory(jedis, mallAuction.getPackageNo());
                        }

                        //把rabbitmq上的queue删去
                        RabbitUtil.deleteQueue(QUEUE_PRE + mallAuction.getPackageNo());
                    }
                }
            }
        }
        return ServerResponse.createBySuccess("更新成功");
    }

    /**
     * @Date 2018/12/26 15:33
     * @Param [userId, type]
     * @return com.hmall.common.ServerResponse
     * @Description  列出个人竞拍的列表  1代表竞拍中 2代表竞拍成功 3竞拍失败 4个人竞拍申请
     */
    public ServerResponse<PageVo> listSelfAuction(Integer userId, Integer type, Integer pageNum, Integer pageSize) {

        //对于竞拍中的数据在redis里面
        //感觉不是很好,或许可以用一个redis-list来维护一个packageNo列表
        //2018/12/28 也不行list用来维护一系列的消息条目比较好
        //先去数据库查询正在竞拍的竞拍编号列表
        //再去nosql中得到具体信息
        List<AuctionSelfVo> auctionSelfVoList;
        if(type == 1) {
            Calendar calendar = Calendar.getInstance();
            Date nowTime = calendar.getTime();
//            List<Long> packageNoList = mallAuctionMapper.selectGoingByTime(nowTime);

            //1.剔除自己没有资格的竞拍
            List<Long> packageNoList = mallAuctionMapper.selectGoingByTimeWithAuth(nowTime, userId);



            try(Jedis jedis = jedisPool.getResource()) {
                String key;
                auctionSelfVoList = new ArrayList<>();
                BigDecimal highestPrice;
                for (Long packageNo : packageNoList) {
                    key = AuctionPool + packageNo;
                    highestPrice = getHighestPrice(jedis, key);
                    key += "-" + userId;
                    BigDecimal selfPrice = new BigDecimal(0.0);
                    if (jedis.exists(key)) {
                        selfPrice = new BigDecimal(jedis.get(key));
                    }
                    MallAuction mallAuction = mallAuctionMapper.selectByPackageNo(packageNo);
                    AuctionSelfVo auctionSelfVo = new AuctionSelfVo();
                    auctionSelfVo.setPackageName(mallAuction.getPackageName());
                    auctionSelfVo.setEndTime(mallAuction.getEndTime());
                    auctionSelfVo.setStartTime(mallAuction.getStartTime());
                    auctionSelfVo.setLowestPrice(mallAuction.getLowestPrice());
                    Long restTime = mallAuction.getEndTime().getTime() - calendar.getTime().getTime();
                    auctionSelfVo.setRestTime(restTime);
                    auctionSelfVo.setSelfPrice(selfPrice);
                    auctionSelfVo.setAuctionCount(mallAuction.getAuctionCount());
                    auctionSelfVo.setPackageNo(packageNo.toString());
                    auctionSelfVo.setHighestPrice(highestPrice);
                    MallAuctionApply mallAuctionApply = mallAuctionApplyMapper.selectByPackageNo(userId, packageNo);
                    auctionSelfVo.setApplyStatus(mallAuctionApply.getStatus());
                    auctionSelfVo.setStatus(mallAuction.getStatus());
                    auctionSelfVoList.add(auctionSelfVo);
                }
            }
            //2表示竞拍成功 3表示竞拍失败
            //对应 数据库  2,4 以及 3
        }else if(type == 2 || type == 3){
            if(type == 2) {
                type = 1;
            } else {
                type = 0;
            }
            auctionSelfVoList = mallAuctionHistoryMapper.selectSelfVoWithType(type, userId);
            //设置最高价
            for(AuctionSelfVo auctionSelfVo : auctionSelfVoList){
                MallAuction mallAuction = mallAuctionMapper.selectByPackageNo(Long.valueOf(auctionSelfVo.getPackageNo()));
                auctionSelfVo.setHighestPrice(mallAuction.getHighestPrice());
                auctionSelfVo.setFinishPrice(mallAuction.getHighestPrice());
            }
           /// return ServerResponse.createBySuccess(auctionSelfVoList);
        }else if(type == 4){
            auctionSelfVoList = mallAuctionApplyMapper.selectSelfVoByUserId(userId);


        }else if(type == 5){
            //可能不必写choose  sql太复杂了
            //以后sql优化可以写进去
            auctionSelfVoList = mallAuctionHistoryMapper.selectSelfVoWithTypeExtra(userId);
            for(AuctionSelfVo auctionSelfVo : auctionSelfVoList){
                MallAuction mallAuction = mallAuctionMapper.selectByPackageNo(Long.valueOf(auctionSelfVo.getPackageNo()));
                auctionSelfVo.setHighestPrice(mallAuction.getHighestPrice());
                auctionSelfVo.setStatus(mallAuction.getStatus());
                auctionSelfVo.setFinishPrice(mallAuction.getHighestPrice());
            }
        } else{
            return ServerResponse.createByErrorMessage("请输入正确的类型");
        }

        //封装一个默认图片2019/1/9 PC端
        auctionSelfVoList.forEach(auctionSelfVo -> auctionSelfVo.setDefaultImg(AUCTION_DEFAULT_IMG));


        //个人竞拍少，直接分页
        int count = auctionSelfVoList.size();
        int start = (pageNum - 1) * pageSize;
        int end = Math.min(start + pageSize, count);
        auctionSelfVoList = auctionSelfVoList.subList(start, end);
        PageVo pageVo = new PageVo(pageNum, pageSize, count, auctionSelfVoList);
        return ServerResponse.createBySuccess(pageVo);

    }

    /**
     * @Date 2018/12/27 9:40
     * @Param [userId, telPhone, packageNo]
     * @return com.hmall.common.ServerResponse
     * @Description  用户提交个人申请
     */
    public ServerResponse applyAuction(Integer userId, String phone, Long packageNo) {

        //如果当前时间已经超过竞拍时间,不能进行申请
        MallAuction mallAuction = mallAuctionMapper.selectByPackageNo(packageNo);
        Calendar calendar = Calendar.getInstance();
        if(calendar.getTime().getTime() > mallAuction.getStartTime().getTime()){
            return ServerResponse.createByErrorMessage("竞拍已经开始，无法提交申请");
        }

        SysUserDept sysUserDept = sysUserDeptMapper.selectbyUserId(userId);
        if(sysUserDept == null){
            return ServerResponse.createByErrorMessage("您还未绑定公司，无法提交竞拍申请");
        }
        //不能重复提交
        ServerResponse response = apply(userId, packageNo, calendar, phone);
        if(response.getStatus() != 0){
            return response;
        }
        try {
            jpushController.backPushMessage(userId, 11, packageNo.toString());
        }catch (Exception e){

        }



       return ServerResponse.createBySuccess("您已成功提交申请，请耐心等待审核通过");
    }

    @Transactional
    ServerResponse apply(Integer userId, Long packageNo, Calendar calendar, String phone){
        int status = 0;
        MallAuctionApply mallAuctionApply = mallAuctionApplyMapper.selectByPackageNoWithStatus(userId, packageNo, status);
        if(mallAuctionApply != null){
            return ServerResponse.createByErrorMessage("您对本次竞拍已经提交过申请，请勿重复提交");
        }


        //申请中
        int applyStatus = 0;
        mallAuctionApply = new MallAuctionApply(userId, packageNo, applyStatus, phone);
        mallAuctionApply.setCreateTime(calendar.getTime());
        try {
            mallAuctionApplyMapper.insert(mallAuctionApply);
        }catch (Exception e){
            return ServerResponse.createByErrorMessage("提交申请失败，请重新提交");
        }
        return ServerResponse.createBySuccess();
    }

    /**
     * @Date 2018/12/27 14:49
     * @Param [type]
     * @return com.hmall.common.ServerResponse
     * @Description //TODO 1代表竞拍中规则  2代表预热规则
     */
    public ServerResponse<AuctionRuleVo> getAuctionRule(Integer type, Long packageNo) {


        String margin;
        if(packageNo == null || "".equals(packageNo)) {
            margin = "XXX";
        }else{
            MallAuction mallAuction = mallAuctionMapper.selectByPackageNo(packageNo);
            if(mallAuction == null || (mallAuction != null && mallAuction.getMargin() == null)){
            margin = "XXX";
            }else {
                margin = mallAuction.getMargin().toString();
            }
        }
        AuctionRuleVo auctionRuleVo = new AuctionRuleVo();
        auctionRuleVo.setMargin(margin);
        if(type == 1){
            auctionRuleVo.setTitle("竞拍规则");
            List<String> auctionRuleDetail = new ArrayList<>();
            auctionRuleDetail.add("1、竞拍时间为每日10:00-13:00。在规定时间段内，价高者得。");
            auctionRuleDetail.add("2、竞拍活动中的产品均为线上开单，只有从竞拍入口才能进行购买。");
            auctionRuleDetail.add("3、本活动需在商品预热阶段提交竞拍押金，以获取竞拍资格。");
            auctionRuleDetail.add("4、竞拍结束后，未竞拍成功用户，竞拍押金将于3-7个工作日内退还；竞拍成功用户，保证金将于货款结清后3-7个工作日内退还。");
            auctionRuleDetail.add("5、竞拍同等出价情况下，购买竞拍份额较多者优先获得竞拍产品成功资格；竞拍同等出价且竞拍份额相同情况下，率先举价竞拍者优先获得竞拍产品成功资格。");
            auctionRuleVo.setRuleDetailList(auctionRuleDetail);
        }else if(type == 2){
            auctionRuleVo.setTitle("竞拍规则");
            List<String> auctionRuleDetail = new ArrayList<>();
            auctionRuleDetail.add("申请竞拍资格需缴纳" + margin + "元保证金");
            auctionRuleDetail.add("1、保证金缴纳方式：提交申请后，请及时将" + margin + "元汇入华鼎公司账户，我们会将其冻结。");
            auctionRuleDetail.add("2、保证金使用说明：缴纳押金后，即可参与商品竞拍，直至押金解冻。");
            auctionRuleDetail.add("3、保证金不可抵用货款；若如果拍中后悔单，则不予退还" + margin+ "元保证金，且1个月内无法参与竞拍。");
            auctionRuleDetail.add("4、保证金解冻说明：竞拍结束后，未竞拍成功用户，保证金将于3-7个工作日内退还；竞拍成功用户，保证金将于货款结清后3-7个工作日内退还。");
            auctionRuleVo.setRuleDetailList(auctionRuleDetail);
        }else if(type == 3){
            auctionRuleVo.setTitle("竞拍规则");
            List<String> auctionRuleDetail = new ArrayList<>();
            auctionRuleDetail.add("1、竞拍时间为每日10:00-13:00。在规定时间段内，价高者得。");
            auctionRuleDetail.add("2、竞拍活动中的产品均为线上开单，只有从竞拍入口才能进行购买。");
            auctionRuleDetail.add("3、本活动需在商品预热阶段缴纳" + margin + "元保证金，以获取竞拍资格。");
            auctionRuleDetail.add("（1）保证金缴纳方式：提交申请后，请及时将" + margin + "元汇入华鼎公司账户，我们会将其冻结；");
            auctionRuleDetail.add("（2）保证金使用说明：缴纳押金后，即可参与商品竞拍，直至押金解冻；");
            auctionRuleDetail.add("（3）保证金不可抵用货款；若如果拍中后悔单，则不予退还" + margin + "元保证金，且1个月内无法参与竞拍；");
            auctionRuleDetail.add("（4）保证金解冻说明：竞拍结束后，未竞拍成功用户，保证金将于3-7个工作日内退还；竞拍成功用户，保证金将于货款结清后3-7个工作日内退还。");
            auctionRuleDetail.add("4、竞拍加价，每次加价不得低于最低加价限额；同一用户多次出价，其竞拍价以该用户最后一次喊价价格为准。");
            auctionRuleVo.setRuleDetailList(auctionRuleDetail);
        }else{
            return ServerResponse.createByErrorMessage("请输入正确的竞拍规则类型");
        }
        return ServerResponse.createBySuccess(auctionRuleVo);
    }

    public ServerResponse pushAuctionApply(Integer userId, Long packageNo, Integer auctionType) throws IOException {

        MallAuctionApply mallAuctionApply = mallAuctionApplyMapper.selectByPackageNo(userId, packageNo);
        if(mallAuctionApply == null){
            return ServerResponse.createByErrorMessage("没有正确的竞拍申请信息");
        }
        String exchange = AUCTION_PUBLIC_EXCHG;
        String packageName = mallAuctionMapper.selectByPackageNo(mallAuctionApply.getPackageNo()).getPackageName();

        Calendar calendar = Calendar.getInstance();
        calendar.setTime(mallAuctionApply.getCreateTime());
        Integer year = calendar.get(Calendar.YEAR);
        Integer month = calendar.get(Calendar.MONTH) + 1;
        Integer day = calendar.get(Calendar.DAY_OF_MONTH);
        Integer hour = calendar.get(Calendar.HOUR_OF_DAY);
        Integer min = calendar.get(Calendar.MINUTE);

        String username = userMapper.selectByPrimaryKey(userId).getUsername();

        //同意之后需要进行绑定
        //PC-,ANDROID-, IOS-
        List<String> list = Arrays.asList("PC-", "IOS-", "ANDROID-");
        list.forEach( str -> RabbitUtil.bindQueue(exchange, QUEUE_PRE + packageNo.toString(), str + username));


        String title = "竞拍信息";

        String body;
        if(auctionType == 1) {
             body = "您好，您于" + year + "年" + month + "月" + day + "日" + hour + "时" + min + "分申请的" + packageName + "商品竞拍资格已审核通过，请您密切关注本次竞拍相关事宜，以免错过竞拍时限。";
        }else{
            body = "您好，您于" + year + "年" + month + "月" + day + "日" + hour + "时" + min + "分申请的" + packageName + "商品竞拍资格审核失败，请您密切关注本次竞拍相关事宜，以免错过竞拍时限。";
        }
        String type = "auctionApply";
        jpushController.jPushMethod(title, body, username, type, packageNo.toString());
        return ServerResponse.createBySuccess("推送成功");
    }


    public ServerResponse test(Long packageNo, Integer userId, String device) {

        String username = userMapper.selectByPrimaryKey(userId).getUsername();
        RabbitUtil.bindQueue(AUCTION_PUBLIC_EXCHG, QUEUE_PRE + packageNo.toString(), device + username);
        Map map = new HashMap();
        map.put("auctionCount", 1);
        map.put("packageNo", packageNo);
        map.put("highestPrice", 100);
        Gson gson = new Gson();
        String jsonStr = gson.toJson(map);
        RabbitUtil.rabbitPushForQueue(AUCTION_PUBLIC_EXCHG, QUEUE_PRE + packageNo, jsonStr);
        return ServerResponse.createBySuccess();
    }
}
